Skip to content

Expose transaction receipt fields#507

Merged
bsiaotickchong merged 2 commits into
mainfrom
bstc/grid-transaction-receipt-fields
May 28, 2026
Merged

Expose transaction receipt fields#507
bsiaotickchong merged 2 commits into
mainfrom
bstc/grid-transaction-receipt-fields

Conversation

@bsiaotickchong
Copy link
Copy Markdown
Contributor

@bsiaotickchong bsiaotickchong commented May 26, 2026

Summary

  • Add optional transactionHash to reconciliationInstructions for destination-side crypto settlement receipt data.
  • Make reference optional so reconciliation instructions can contain only a transaction hash when no payment reference exists.
  • Add optional fees to incoming transactions, denominated in the receiving currency's smallest unit.
  • Rebuild bundled OpenAPI specs for openapi.yaml and mintlify/openapi.yaml.

Implementation Note

The public API stays storage-agnostic. In webdev, transactionHash is populated from hash-bearing Grid settlement references, including the existing USDC_SOLANA settlement reference type and the new generic CRYPTO type.

Testing

  • make build
  • make lint

@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment May 28, 2026 6:01pm

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 26, 2026

✱ Stainless preview builds for grid

This PR will update the grid SDKs with the following commit messages.

cli

feat: Expose transaction receipt fields

csharp

feat: Expose transaction receipt fields

go

feat: Expose transaction receipt fields

kotlin

feat: Expose transaction receipt fields

openapi

feat: Expose transaction receipt fields

php

feat: Expose transaction receipt fields

python

feat: Expose transaction receipt fields

ruby

feat: Expose transaction receipt fields

typescript

feat: Expose transaction receipt fields

Edit this comment to update them. They will appear in their respective SDK's changelogs.

⚠️ grid-openapi studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗

New diagnostics (2 error, 10 note)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/AgentAccountRestrictions`
⚠️ grid-ruby studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ✅ (prev: build ⏭️) → lint ❗ (prev: lint ✅) → test ✅

New diagnostics (2 error, 10 note)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/AgentAccountRestrictions`
⚠️ grid-typescript studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ❗ (prev: build ⏭️) → lint ❗ (prev: lint ⏭️) → test ❗ (prev: test ✅)

New diagnostics (2 error, 10 note)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/AgentAccountRestrictions`
⚠️ grid-python studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ✅

pip install https://pkg.stainless.com/s/grid-python/69008289e3703437a69675ddda646f1b1178b434/grid-0.0.1-py3-none-any.whl
New diagnostics (2 error, 10 note)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/AgentAccountRestrictions`
⚠️ grid-csharp studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ❗ (prev: build ⏭️) → lint ❗ (prev: lint ⏭️) → test ❗

New diagnostics (3 error, 12 note)
InvalidInternalState: Internal error, please try again.
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
⚠️ grid-go studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ✅ (prev: build ⏭️) → lint ❗test ❗

go get github.com/stainless-sdks/grid-go@97556c53b9db185841d56939e56c54b55675b42b
New diagnostics (5 error, 8 note)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
Model/GeneratedNameClash: Name clash may cause compile errors.
Model/GeneratedNameClash: Name clash may cause compile errors.
Model/GeneratedNameClash: Name clash may cause compile errors.
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
⚠️ grid-php studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗lint ❗ (prev: lint ✅) → test ✅

New diagnostics (4 error, 4 warning, 11 note)

InvalidInternalState: Internal error, please try again.
InvalidInternalState: Internal error, please try again.
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
⚠️ Name/Collision: Possible undesirable name generated for language
⚠️ Name/Collision: Possible undesirable name generated for language
⚠️ Name/Collision: Possible undesirable name generated for language
⚠️ InvalidInternalStateWarning: Something unexpected happened during codegen. Our team has been notified. Your SDK was still generated correctly, and no action is needed on your end. If you need help please reach out to support@stainless.com. --- Cannot have two defs with the same ID.

Provide a slug for at least one def to disambiguate them.

💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
⚠️ grid-kotlin studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ❗

New diagnostics (2 error, 10 note)

Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Java/NameNotAllowed: Encountered name `return` that conflicts with a [Kotlin keyword](https://kotlinlang.org/docs/keyword-reference.html#hard-keywords). Renamed to `return_`.

To provide a different name, use a merge transform.

💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
⚠️ grid-cli studio · code · diff

Your SDK build had at least one new error diagnostic, which is a regression from the base state.
generate ❗build ❗lint ❗test ❗

New diagnostics (2 error, 10 note)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `delete /cards/{id}`
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `get /cards/{id}/transactions`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/EmbeddedWalletConfig`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftExternalAccountCreateInfo`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/SwiftBeneficiary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardMerchant`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardPullSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardRefundSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/CardSettlementSummary`
💡 Model/Recommended: We recommend you use a model for `#/components/schemas/AgentAccountRestrictions`

This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-05-28 18:07:26 UTC

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 26, 2026

Greptile Summary

This PR extends the IncomingTransaction and ReconciliationInstructions schemas to surface crypto receipt data: transactionHash is added as an optional field to ReconciliationInstructions, reference is made optional (previously required), and an optional fees field (int64, smallest currency unit) is added to IncomingTransaction. Both bundled specs (openapi.yaml, mintlify/openapi.yaml) are rebuilt accordingly.

  • IncomingTransaction.fees — clean addition; integer type, minimum: 0, and a clear description.
  • ReconciliationInstructions.transactionHash — new optional crypto hash field; no format/pattern constraint, which is acceptable for a cross-chain field.
  • ReconciliationInstructions.reference — made optional, but the field description still says "must be included with the payment", and no schema constraint prevents an empty {} object when both fields are absent.

Confidence Score: 3/5

Safe to merge once the empty-object gap in ReconciliationInstructions is addressed; the fees addition is clean.

Making reference optional without adding any constraint that at least one of reference or transactionHash must be present means a client could receive a reconciliationInstructions: {} object that carries no matching data at all. That is a logical hole in the schema contract that quietly allows bad data to pass validation. The fees addition and both bundle rebuilds look correct.

openapi/components/schemas/common/ReconciliationInstructions.yaml — the optionality change and stale description both need attention before merging.

Important Files Changed

Filename Overview
openapi/components/schemas/common/ReconciliationInstructions.yaml Makes reference optional and adds transactionHash; stale "must be included" description and no constraint preventing a fully-empty object.
openapi/components/schemas/transactions/IncomingTransaction.yaml Adds optional fees field (int64, minimum 0) to incoming transactions; straightforward and well-formed.
openapi.yaml Generated bundle reflecting the source schema changes; no issues beyond those already flagged in the source files.
mintlify/openapi.yaml Mintlify-targeted generated bundle; identical changes to openapi.yaml, no independent issues.

Sequence Diagram

sequenceDiagram
    participant Client
    participant GridAPI

    Client->>GridAPI: "GET /transactions/{id}"
    GridAPI-->>Client: IncomingTransaction response
    note over Client,GridAPI: New optional fields in response
    note right of GridAPI: fees (int64, min 0)<br/>reconciliationInstructions.transactionHash
    note right of GridAPI: reconciliationInstructions.reference<br/>is now optional (was required)
    Client->>Client: Handle reconciliationInstructions
    alt reference present
        Client->>Client: Use reference for payment matching
    else transactionHash present
        Client->>Client: Use transactionHash for crypto receipt
    else neither present (now schema-valid)
        Client->>Client: Empty object — no matching data
    end
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
openapi/components/schemas/common/ReconciliationInstructions.yaml:3-8
**Stale "must be included" wording after making `reference` optional**

The `reference` field description still reads "must be included with the payment", but the `required` constraint was just removed. Any API consumer reading this description will think the field is mandatory when the schema now treats it as optional — the two are in direct conflict.

### Issue 2 of 2
openapi/components/schemas/common/ReconciliationInstructions.yaml:1-13
**Schema now accepts a fully-empty `ReconciliationInstructions` object**

With both `reference` and `transactionHash` optional, the object `{}` is valid per the schema. The PR description states the intent is to allow a transaction hash *when no payment reference exists*, implying at least one field should always be present. A `minProperties: 1` constraint (or an `anyOf` / `oneOf` requiring at least one of the two fields) would close the gap and prevent a semantically meaningless empty object from passing validation.

Reviews (1): Last reviewed commit: "feat(transactions): expose receipt recon..." | Re-trigger Greptile

Comment thread openapi/components/schemas/common/ReconciliationInstructions.yaml
Comment thread openapi/components/schemas/common/ReconciliationInstructions.yaml
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

⚠️ Breaking OpenAPI changes detected

This PR introduces breaking changes to openapi.yaml:

API Changelog 2025-10-13 vs. 2025-10-13

API Changes

GET /agents/approvals

  • ⚠️ the response property data/items/transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

GET /agents/me/actions

  • ⚠️ the response property data/items/transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

GET /agents/me/actions/{actionId}

  • ⚠️ the response property transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /agents/me/quotes/{quoteId}/execute

  • ⚠️ the response property transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

GET /agents/me/transactions

  • ⚠️ the response property data/items/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

GET /agents/me/transactions/{transactionId}

  • ⚠️ the response property oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /agents/me/transfer-in

  • ⚠️ the response property transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 201

POST /agents/me/transfer-out

  • ⚠️ the response property transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 201

POST /agents/{agentId}/actions/{actionId}/approve

  • ⚠️ the response property transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /agents/{agentId}/actions/{actionId}/reject

  • ⚠️ the response property transaction/allOf[#/components/schemas/TransactionOneOf]/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /sandbox/uma/receive

  • ⚠️ the response property allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

GET /transactions

  • ⚠️ the response property data/items/oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

GET /transactions/{transactionId}

  • ⚠️ the response property oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /transactions/{transactionId}/approve

  • ⚠️ the response property allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /transactions/{transactionId}/reject

  • ⚠️ the response property allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 200

POST /transfer-in

  • ⚠️ the response property oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 201

POST /transfer-out

  • ⚠️ the response property oneOf[subschema #1: Incoming Transaction]/allOf[subschema #2]/reconciliationInstructions/reference became optional for the status 201

Detected by oasdiff. This PR will need approval from an API reviewer before merge.

@bsiaotickchong bsiaotickchong merged commit 797df4a into main May 28, 2026
7 of 8 checks passed
@bsiaotickchong bsiaotickchong deleted the bstc/grid-transaction-receipt-fields branch May 28, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Introduces a breaking change to the OpenAPI spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants